//  this library.
import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:hktk_app/exception/dao_exception.dart';
import 'package:hktk_app/model/data_model.dart';
import 'package:hktk_app/model/my/local_file_model.dart';
import 'package:hktk_app/util/dao_util.dart';
import 'package:http/http.dart' as http;
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart';

/// 下载使用接口
class DownloadDao {
  /// 下载临时文件
  static Future<File> downloadTemporaryFile({
    required String url,
    required String fileName,
  }) async {

    Uri uri = Uri.parse(url);
    // 发起下载请求
    final response = await http.get(uri);
    // 检查请求状态
    if (response.statusCode == 200) {
      // 获取临时目录路径
      final tempDir = await getTemporaryDirectory();
      final tempPath = tempDir.path;

      // 创建文件
      var file = File("$tempPath/$fileName");

      // 将下载的内容写入文件
      await file.writeAsBytes(response.bodyBytes);
      // 返回文件路径
      return file;
    } else {
      throw DaoException(msg: "加载失败，请重试", code: -2);
    }
  }

  // filePath：被移动的文件路径
  // dataModel：相关科目数据
  // name：文件名称
  // type：文件类型
  /// 移动临时文件到永久文件方法
  static Future<bool> fileMove({
    required String filePath,
    required DataModel dataModel,
    required String name,
    required String type,
  }) async {
    try {
      File file = File(filePath);
      // 创建文件
      File saveFile = await _createFile(
        dataModel: dataModel,
        name: name,
        type: type,
      );
      // 将内容写入文件
      List<int> asBytes = await file.readAsBytes();
      await saveFile.writeAsBytes(asBytes);
      return true;
    } catch (e) {
      if (e is DaoException) {
        throw DaoException(msg: e.msg, code: e.code);
      }
      return false;
    }
  }

  /// 获取永久存储路径
  static Future<String> _getFilePath() async {
    String path = "";
    if (Platform.isAndroid) {
      var directory = await getExternalStorageDirectory();
      if (directory != null) {
        path = directory.path;
      } else {
        throw DaoException(msg: "未知错误，请重试", code: -1);
      }
    } else if (Platform.isIOS) {
      var directory = await getLibraryDirectory();
      path = directory.path;
    }

    return path;
  }

  /// 创建文件
  static Future<File> _createFile({
    required DataModel dataModel,
    required String name,
    required String type,
  }) async {
    String path1 = await _getFilePath();

    // 计算文件路径
    String path =
        "$path1/$downPath/${dataModel.industryName}/${dataModel.examName}/${dataModel.categoryName}/$name.$type";
    // 创建文件
    File saveFile = File(path);
    if (saveFile.existsSync()) {
      // 存在提示
      // throw DaoException(msg: "该文件已存在", code: -1);
      // 删除
      await saveFile.delete();
    }
    saveFile = await File(path).create(recursive: true);
    return saveFile;
  }
  static Future<File> _createFileWithExamId({
    required DataModel dataModel,
    required String name,
    required String type,
  }) async {
    String path1 = await _getFilePath();

    // 计算文件路径
    String path =
        "$path1/$downPath/${dataModel.industryName}/${dataModel.examName}/$name.$type";
    // 创建文件
    File saveFile = File(path);
    if (saveFile.existsSync()) {
      // 存在提示
      // throw DaoException(msg: "该文件已存在", code: -1);
      // 删除
      await saveFile.delete();
    }
    saveFile = await File(path).create(recursive: true);
    return saveFile;
  }

  /// 下载永久文件
  static Future<bool> downloadFile({
    required String url,
    required DataModel dataModel,
    required String name,
    required String type,
  }) async {
    try {
      Uri uri = Uri.parse(url);
      // 发起下载请求
      final response = await http.get(uri);
      // 检查请求状态
      if (response.statusCode == 200) {
        // 创建文件
        File saveFile = await _createFile(
          dataModel: dataModel,
          name: name,
          type: type,
        );
        // 将数据写入文件
        await saveFile.writeAsBytes(response.bodyBytes);

        return true;
      } else {

        return false;
      }
    } catch (e) {
      if (e is DaoException) {
        throw DaoException(msg: e.msg, code: e.code);
      }
      return false;
    }
  }

  /// 下载永久文件
  static Future<bool> downloadFileWithExamId({
    required String url,
    required DataModel dataModel,
    required String name,
    required String type,
  }) async {
    try {
      Uri uri = Uri.parse(url);
      // 发起下载请求
      final response = await http.get(uri);
      // 检查请求状态
      if (response.statusCode == 200) {
        // 创建文件
        File saveFile = await _createFileWithExamId(
          dataModel: dataModel,
          name: name,
          type: type,
        );
        // 将数据写入文件
        await saveFile.writeAsBytes(response.bodyBytes);
        return true;
      } else {
        return false;
      }
    } catch (e) {
      if (e is DaoException) {
        throw DaoException(msg: e.msg, code: e.code);
      }
      return false;
    }
  }
  /// 获取本地相关文件
  static Future<List<LocalFileModel>> getLocalFiles({
    required String industryName,
    required String examName,
    required String categoryName,
  }) async {
    String path1 = await _getFilePath();

    // 计算文件目录
    String path = "$path1/$downPath/$industryName/$examName/$categoryName";
    // 创建文件夹
    var dir = Directory(path);
    // 判断文件夹是否存在2
    if (!dir.existsSync()) {
      return <LocalFileModel>[];
    }
    Stream<FileSystemEntity> list = dir.list();
    return list.map((FileSystemEntity entity) {
      String path = entity.path;
      return LocalFileModel(
        name: path.substring(path.lastIndexOf("/") + 1),
        type: path.substring(path.lastIndexOf(".") + 1),
        path: path,
      );
    }).toList();
  }

  /// 获取缓存
  static Future<double> loadApplicationCache() async {
    /// 获取文件夹
    Directory directory = await getTemporaryDirectory();

    /// 获取缓存大小
    double value = await _getTotalSizeOfFilesInDir(directory);
    return value;
  }

  /// 循环计算文件的大小（递归）
  static Future<double> _getTotalSizeOfFilesInDir(
      final FileSystemEntity file,
      ) async {
    if (file is File) {
      int length = await file.length();
      return double.parse(length.toString());
    }
    if (file is Directory) {
      final List<FileSystemEntity> children = file.listSync();
      double total = 0;
      for (FileSystemEntity child in children) {
        total += await _getTotalSizeOfFilesInDir(child);
      }
      return total;
    }
    return 0;
  }

  /// 缓存大小格式转换
  static String formatSize(double value) {
    List<String> unitArr = ["B", "K", "M", "G"];
    int index = 0;
    while (value > 1024) {
      index++;
      value = value / 1024;
    }
    String size = value.toStringAsFixed(2);
    return size + unitArr[index];
  }

  static Future<void> clearApplicationCache() async {
    Directory directory = await getTemporaryDirectory();
    //删除缓存目录
    await _deleteDirectory(directory);
  }

  /// 递归方式删除目录
  static Future<Null> _deleteDirectory(FileSystemEntity file) async {
    if (file is Directory) {
      final List<FileSystemEntity> children = file.listSync();
      for (final FileSystemEntity child in children) {
        await _deleteDirectory(child);
      }
    }
    await file.delete();
  }

  /// 获取版本号方法
  static Future<String> getAppVersion() async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    return packageInfo.version;
  }
}
